var utils = {
    //获取链接参数值
    urlQuery : function (name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null)
            return decodeURI(r[2]);
        return null;
    },
    //拼接url参数
    urlWithParams: function(url = "", params = {}) {
        const queryString = Object.keys(params).map(key => {
            return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
        }).join('&');
        return url + (url.includes('?') ? '&' : '?') + queryString;
   },
    //当前时间戳
    getLocalTime : function (t, type) {
        t = $.trim(t);
        var _date = ['', ' 00:00:00', ' 23:59:59']
        if (type && t) {//传参数模式
            t = t.substr(0, 10) + _date[type]
        }
        if (type && !t) 
            return '';
        var timestamp = t ? parseInt(new Date(t).valueOf() / 1000) : parseInt(new Date().valueOf() / 1000);
        return timestamp;
    },
    //数组拼接字符串，data数据集合，fieldName字段名，splitStr分割符号（默认,）
    stringJoin : function (data, fieldName, splitStr) {
        splitStr = splitStr || ",";
        var arrys = $.map(data, function (v) {
            if(fieldName)
                return v[fieldName];
            else
                return v;
        });
        return arrys.join(splitStr);
    },
    //split分割成数组
    splitToInts: function (str, splitStr) {
        if (!str) return [];
        if (!splitStr) splitStr = ',';
        return str.split(splitStr).map(Number);
    },
    //缓存转对象处理
    localStorage:{
        setItem(key, value){
            if (!value)
                localStorage.setItem(key, "");
            else
                localStorage.setItem(key, JSON.stringify(value));
        },
        getItem(key){
            if(!localStorage.getItem(key))
                return null;
            return JSON.parse(localStorage.getItem(key));
        }
    },
    //获取当前时间，格式YYYY-MM-DD
    getDateFormat(date) {
        if(!date)
            date = new Date();
        var seperator1 = "-";
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        var strDate = date.getDate();
        if (month >= 1 && month <= 9) {
            month = "0" + month;
        }
        if (strDate >= 0 && strDate <= 9) {
            strDate = "0" + strDate;
        }
        var currentdate = year + seperator1 + month + seperator1 + strDate;
        return currentdate;
    },
    //获取时间周期，
    getRangeFormatDate(num) {//num是正数表示当天之后的时间，num负数表示当天之前的时间，0表示今天
         
        var date1 = new Date();
        var year1 = date1.getFullYear();
        var month1 = date1.getMonth() + 1;
        var day1 = date1.getDate();
        if (month1 >= 1 && month1 <= 9)  month1 = "0" + month1;  
        if (day1 >= 0 && day1 <= 9)  day1 = "0" + day1;
        var time1 = year1 + "-" + month1 + "-" + day1 ;

        var date2 = new Date(date1);
        date2.setDate(date1.getDate() + Number(num));
        var year2 = date2.getFullYear();
        var month2 = date2.getMonth() + 1;
        var day2 = date2.getDate();
        if (month2 >= 1 && month2 <= 9)  month2 = "0" + month2;  
        if (day2 >= 0 && day2 <= 9)  day2 = "0" + day2;
        var time2 = year2 + "-" + month2 + "-" + day2;
        return time2 + " 至 " + time1;
    },
    //获取当前时间，格式YYYY-MM-DD HH:MM:SS
    getTimeFormat(date) {
        if(!date)
            date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
        var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
        var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
        var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
        var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
        return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
    },
    // 时长转时分秒
    SecondToDate(t) {
        if (null != t && "" != t) {
            if (t > 60 && t < 60 * 60) {
                t = parseInt(t / 60.0) + "分" + parseInt((parseFloat(t / 60.0) -
                    parseInt(t / 60.0)) * 60) + "秒";
            } else if (t >= 60 * 60 && t < 60 * 60 * 24) {
                t = parseInt(t / 3600.0) + "时" + parseInt((parseFloat(t / 3600.0) -
                    parseInt(t / 3600.0)) * 60) + "分" +
                    parseInt((parseFloat((parseFloat(t / 3600.0) - parseInt(t / 3600.0)) * 60) -
                        parseInt((parseFloat(t / 3600.0) - parseInt(t / 3600.0)) * 60)) * 60) + "秒";
            } else if (t >= 60 * 60 * 24) {
                t = parseInt(t / 3600.0 / 24) + "天" + parseInt((parseFloat(t / 3600.0 / 24) -
                    parseInt(t / 3600.0 / 24)) * 24) + "时" + parseInt((parseFloat(t / 3600.0) -
                        parseInt(t / 3600.0)) * 60) + "分" +
                    parseInt((parseFloat((parseFloat(t / 3600.0) - parseInt(t / 3600.0)) * 60) -
                        parseInt((parseFloat(t / 3600.0) - parseInt(t / 3600.0)) * 60)) * 60) + "秒";
            } else {
                t = parseInt(t) + "秒";
            }

        } else {
            t = parseInt(t) + "秒";
        }
        return t;
    },
    getGuid() {
        function S4() {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        }
        return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
    },
    //延时函数(同步)
    sleep(time){
        var startTime = new Date().getTime() + parseInt(time, 10);
        while(new Date().getTime() < startTime) {}
    },
    //延时函数(异步)
    //用法：(async function() {
    //  console.log('Do some thing, ' + new Date());
    //  await sleep(3000);
    //  console.log('Do other things, ' + new Date());
    //})();
    sleepAsync(time){
        return new Promise((resolve) => setTimeout(resolve, time));
    },
    //findWhere(data, v => v.parent_id == parentid) //查找配对的所有数据
    findWhere(data, where, select) {
        if (!data) return [];
        if (typeof data == "object") data = Object.values(data);
        if(!select)
            return data.filter(where);
        else
            return data.filter(where).map(select);
    },
    //find(data, v => v.parent_id == parentid) //查找配对的第一条数据
    find(data, func) {
        if (!data) return null;
        return data.find(func);
    },
    //select(data, v => v.parent_id) or .select(data, x => ({ id: x.id, name: x.name })) //返回新的数据集合
    select(data, func){
        if (!data) return [];
        return data.map(func);
    },
    //any(data, v =>v.parent_id == parentid) //查到记录是否存在，存在返回true
    any(data, func) {
        if (!data) return false;
        return data.findIndex(func) != -1;
    },
    //arr是否包含在集合array内
    contains(array, arr) {
        return $.inArray(arr, array) != -1
    },
    //排序，排序字段sortName、isDesc：false升序、true降序
    sort(data, sortName, isDesc = false) {
        if (!isDesc) {
            data.sort(function (a, b) {
                if (typeof a == "number" && typeof b == "number")
                   return a[sortName] - b[sortName];
                else
                   return a[sortName].charCodeAt() - b[sortName].charCodeAt();
            });
        }
        else {
            data.sort(function (a, b) {
                if (typeof a == "number" && typeof b == "number")
                   return b[sortName] - a[sortName];
                else
                   return b[sortName].charCodeAt() - a[sortName].charCodeAt();
            });
        }
        return data;
    },
    //在data数组中删除obj对象
    remove(data, obj){
        for(var i = 0; i < data.length; i++){
            if(data[i] == obj){
                //删除下标为i的元素
                data.splice(i, 1);
            }
        }
    },
    //去重
    distinct(array){
        var temp = [];
        var index = [];
        var l = array.length;
        for(var i = 0; i < l; i++) {
            for(var j = i + 1; j < l; j++){
                if (array[i] === array[j]){
                    i++;
                    j = i;
                }
            }
            temp.push(array[i]);
            index.push(i);
        }
        return temp;
    },
    //对象集合通过字段去重，unique(arr,"id")
    unique(arr, field){
        var map = {};
        var res = [];
        for (var i = 0; i < arr.length; i++) {
            if (!map[arr[i][field]]) {
                map[arr[i][field]]=1;
                res.push(arr[i]);
            }
        }
         return res;
    },
    //深拷贝数据
    clone(data) {
        if ($.type(data) == "array")
            return $.extend(true, [], data);
        else
            return $.extend(true, {}, data);
    },
    //方法组切换，toggle(ele, [fn1,fn2,fn3]);
    toggle(ele, fns) {
        ele = $(ele);
        if (!ele.attr("toggleNumber"))
            ele.attr("toggleNumber", 0);
        var num = Number(ele.attr("toggleNumber"));
        if (fns) {
            fns[num]();
            if (num + 1 >= fns.length)
                ele.attr("toggleNumber", 0);                
            else
                ele.attr("toggleNumber", num + 1);
        }
    },
    //滚动到顶部
    scrollTop(elem) {
        $(elem || "html,body").animate({ scrollTop: 0}, 300);
    },
    //滚动到底部
    scrollBottom(elem) {
        var elem = elem || "html,body";
        $(elem).animate({scrollTop: $(elem).prop("scrollHeight")}, 300);
    }
};

//动态加载脚本
utils.dynamicJsLoading = function (jsPath, callback, async, afterJs) {
    var js=$("script[src='"+jsPath+"']");
    if(js.length>0) return;

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = jsPath;
    var fn = callback || function(){}; 
    if (async) {
        script.setAttribute("async", true);
        script.setAttribute("defer", "");

        if (script.readyState) {//IE
            script.onreadystatechange = function () {
                if (script.readyState == 'loaded' || script.readyState == 'complete') {
                    script.onreadystatechange = null;
                    console.log("dynamicJsLoading");
                    fn();
                }
            };
        } else {//其他浏览器        
            script.onwaiting = function () {
                console.log("dynamicJsLoading");
                fn();
            };
            script.onload  = function () {
                console.log("dynamicJsLoading");
                script.onload = null;
                fn();
            };
        }
    }

    if(afterJs) {
        $("script[src*='" + afterJs + "']").last().after(script);
    }
    else{
        // document.getElementsByTagName("head")[0].appendChild(script);
        $("script[src*='jquery.min']").last().after(script);
    }

    if(!async) 
        fn();
};

//动态加载css
utils.dynamicCssLoading = function (cssPath, callback, afterCss) {
    var css = $("link[href='" + cssPath + "']");
    if (css.length > 0) return;

    var css = document.createElement('link');
    css.rel = 'stylesheet';
    css.href = cssPath;

    if (afterCss) {
        $("link[href*='" + afterCss + "']").last().after(css);
    }
    else {
        // document.getElementsByTagName("head")[0].appendChild(script);
        $("head").last().append(css);
    }

    if (callback)
        callback();
}

//RequireJS动态加载模块
utils.dynamicRequireJS = function (moduleName, isWinobj) {
    if (isWinobj) {
        if (!window[moduleName]) {
            window[moduleName] = require(moduleName);
        }
        return window[moduleName];
    } else {
        return require(moduleName);
    }
}

//弹出下载对话框，url下载地址，saveName保存文件名
utils.downloadOpenDialog = function (url, saveName, isblank = false) {
    if(!url){
        nlwAlert.error("下载链接不能为空");
        return;
    }
    if (url.indexOf("http") != 0)
        url = utilsConfig.serverDomainUrl + url;
        
    if (!utils.checkUrl(url)) {
        nlwAlert.error("下载链接错误");
        return;
    }

	if(typeof url == 'object' && url instanceof Blob)
	{
		url = URL.createObjectURL(url); // 创建blob地址
	}
	var aLink = document.createElement('a');
    aLink.href = url;
    if(isblank)
        aLink.target = "_blank";
	aLink.download = saveName || ''; // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，file:///模式下不会生效
	var event;
    if (window.MouseEvent)
        event = new MouseEvent('click');
	else
	{
		event = document.createEvent('MouseEvents');
		event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	}
	aLink.dispatchEvent(event);
}

//post方法下载文件，url下载地址，vals表单参数
utils.downloadPostForm = function (url, vals) {
    var form = $("<form></form>");//定义一个form表单
    // form.attr("id", "downloadform");
    form.attr("style", "display:none");//将表单隐藏
    form.attr("target", ""); //_blank
    form.attr("method", "post");
    form.attr("action", utilsConfig.serverDomainUrl + url);
    if(!vals) vals = {};
    vals.controlName = url.split('/')[1];
    vals.actionName = url.split('/')[2];
    vals.time_stamp = utils.getLocalTime();
    vals.token = vals.token ? vals.token: utils.getToken();
    var enc_key = parent.DmConf ? parent.DmConf.data.enc_key : utils.localStorage.getItem("data").enc_key;
    vals.sign = utils.client_method.getSign(vals.controlName, vals.actionName, vals.token, enc_key, vals.time_stamp);

    $.each(vals, function (k, v) {
        var input1 = $("<input>");
        input1.attr("type", "hidden");
        input1.attr("name", k);
        input1.attr("value", v);
        form.append(input1);
    });

    $("body").append(form);//将表单放置在页面中
    form.submit();//表单提交
    form.remove();//移除表单
}

//post方法下载文件，filename可不填
utils.downloadPostAjax = function (url, vals, filename) {
    if (!vals) vals = {};
    vals.controlName = url.split('/')[1];
    vals.actionName = url.split('/')[2];
    vals.time_stamp = utils.getLocalTime();
    vals.token = vals.token ? vals.token : utils.getToken();
    var enc_key = parent.DmConf ? parent.DmConf.data.enc_key : utils.localStorage.getItem("data").enc_key;
    vals.sign = utils.client_method.getSign(vals.controlName, vals.actionName, vals.token, enc_key, vals.time_stamp);
    url = utilsConfig.serverDomainUrl + url;

    var xhr = new XMLHttpRequest();
    xhr.open('post', url, true);
    xhr.responseType = 'blob';
    xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8');
    xhr.setRequestHeader('token', vals.token);
    xhr.send(JSON.stringify(vals));
    // xhr.onreadystatechange = function () {
    xhr.onload = function (obj) {
        if(!filename){
            try {
                filename = xhr.getResponseHeader("Content-Disposition");
                filename = filename.replace("FileName; ", "").replace('attachment;filename=','').replace("filename=", "");
            } 
            catch (error) {
            }
        }
        if (this.status == 200) {
            var blob = this.response;
            var yLink = document.createElement('a');
            yLink.download = filename || utils.getTimeFormat() + ".xls";
            yLink.style.display = 'none';
            // 字符内容转变成blob地址
            yLink.href = URL.createObjectURL(blob);
            // 触发点击
            document.body.appendChild(yLink);
            yLink.click();
            // 然后移除
            document.body.removeChild(yLink);
        }
        else{
            nlwAlert.error("下载文件失败");
        }
    }
}

//获取表单里name和value集合
utils.getFormVal = function (element, isverify) {    
    if (isverify) {
        var bo = utils.verifyForm(element);
        if (bo == false) return false;
    }
    var ele = $(element);
    var data = {};
    var f = ele.serializeArray();
    $.each(f, function () {
        var obj = ele.find("[name='" + this.name + "']");
       
        if (obj.attr("type") == 'checkbox') {
            var vals = [];
            obj.each(function () {
                if ($(this).is(":checked")) {
                    vals.push($(this).val());
                }
            });
            data[this.name] = vals;
        }
        else if (obj.filter("input").hasClass("xm-select-radio")) {
            data[this.name] = this.value ? this.value : -1;
        }
        else if (obj.filter("input").hasClass("xm-select-checkbox")) {
            data[this.name] = this.value ? this.value : '';
        }
        else if (obj.filter("select").length > 0) {
            data[this.name] = this.value ? this.value : -1;
        }
        else {
            data[this.name] = this.value;
        }
    });
    return data;
}

//验证表单是否通过，要添加lay-verify="required"
utils.verifyForm = function (elem) {
    var ele = $(elem);
    if (ele.find("[lay-submit]").length == 0)
        ele.append('<button class="layui-btn layui-btn-sm layui-hide" lay-submit>提交</button>');
    ele.find("[lay-submit]").click();
    var isnoDanger = ele.find("input,select,textarea").filter(".layui-form-danger").length == 0;
    return isnoDanger;
}

//网页打印
utils.webPrint = function (elehtml, isblank = true) {
    var printhtml;
    if ($.type(elehtml) == "string" && elehtml.length > 10) {
        printhtml = elehtml;
    }
    else{
        printhtml = $(elehtml).html();
    }
    
    if(!isblank){
        var oldbody = window.document.body.innerHTML;    
        window.document.body.innerHTML = printhtml;
        window.print();
        window.document.body.innerHTML = oldbody;
    }
    else{
        var wind = window.open("", "print", "toolbar=no,scrollbars=yes,menubar=no,height=800");
        wind.document.body.innerHTML = printhtml;
        wind.print();
        wind.close();
    }
}

//判断浏览器类型
utils.isBrowser = function () {
    var u = navigator.userAgent;
    return {
      ie: u.indexOf('Trident') > -1, //IE内核
      opera: u.indexOf('Presto') > -1, //opera内核
      webkit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
      ff: u.indexOf('Firefox') > -1, //火狐内核Gecko
      mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
      ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios
      android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android
      iPhone: u.indexOf('iPhone') > -1, //iPhone
      iPad: u.indexOf('iPad') > -1, //iPad
      webApp: u.indexOf('Safari') > -1 //Safari
    };
}();

//全局事件广播与侦听，跨页面事件监听
utils.globalEvent = {
    init() {
        function aa(e, listenerName, func) {
            if (e.key == "_globalEvent_" + listenerName) {
                var msg = JSON.parse(e.newValue);
                if (msg.url && location.href.indexOf(msg.url) == -1)
                    return;
                func(msg.data);
            }
        }
        window.onstorage = function (e) {
            // console.log(e.key + ' 键已经从 ' + e.oldValue + ' 改变为 ' + e.newValue + '.');
            var listenerNames = Object.keys(utils.globalEvent.listenerNameList);
            for (let index = 0; index < listenerNames.length; index++) {
                var listenerName = listenerNames[index]
                var func = utils.globalEvent.listenerNameList[listenerName];
                aa(e, listenerName, func);
            }
        };
    },
    //listenerName监听的事件名称，data发送的数据，url发送到指定页面，null则发送到所有监听页
    publicMessage(listenerName, data, url = null) {
        var msg = { data: data, time: new Date().getTime(), url: url }
        localStorage.setItem("_globalEvent_" + listenerName, JSON.stringify(msg));
        if(this.listenerNameList != null){
            if (url && location.href.indexOf(url) == -1)
                return;
            if(this.listenerNameList[listenerName])
               this.listenerNameList[listenerName](data);
        }
    },
    listenerNameList: null,
    //listenerName监听的事件名称，func(data)回调方法及接收的数据
    addListener(listenerName, func) {
        if (typeof (window.onstorage) == "undefined")
            alert("浏览器不支持window.onstorage");
        if (this.listenerNameList == null) {
            this.init();
            this.listenerNameList = {};
        }
        this.listenerNameList[listenerName] = func;
    },
    //事件命名规则：“模块名.操作名”
    listenerNames:[]
};